package com.gydz.interferencenetworkmanagement.common.netty.client;

import com.gydz.interferencenetworkmanagement.common.netty.handler.NettyClientHandler;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioDatagramChannel;

import java.util.Date;
import java.util.concurrent.TimeUnit;

public class UdpNettyClient {

    private static final int MAX_RETRY = 5;     //失败重连次数
    private static final String HOST = "127.0.0.1"; //服务端ip
    private static final int PORT = 8000;           //服务端端口

    public static void main(String[] args) {
        UdpNettyClient udpNettyClient = new UdpNettyClient();
        udpNettyClient.run(HOST,PORT,MAX_RETRY);
    }

    public void run(String host,int port,int maxRetry) {
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        System.out.println("准备运行端口：" + port);
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(workerGroup)     //配置现场模型
                .channel(NioDatagramChannel.class)      //配置IO模型
                .option(ChannelOption.SO_BROADCAST, true)
                .handler(new ChannelInitializer<NioDatagramChannel>() {  //配置处理
                    @Override
                    protected void initChannel(NioDatagramChannel nioDatagramChannel) {
                        nioDatagramChannel.pipeline().addLast(new NettyClientHandler());
                    }
                });
        connect(bootstrap, HOST, PORT, MAX_RETRY);

    }

    private static void connect(Bootstrap bootstrap, String host, int port, int retry) {
        bootstrap.connect(host, port).addListener(future -> {
            if (future.isSuccess()) {
                System.out.println("连接成功!");
            } else if (retry == 0) {
                System.err.println("重试次数已用完，放弃连接！");
            } else {
                // 第几次重连
                int order = (MAX_RETRY - retry) + 1;
                // 本次重连的间隔
                int delay = 1 << order;
                System.err.println(new Date() + ": 连接失败，第" + order + "次重连……");
                bootstrap.config().group().schedule(() -> connect(bootstrap, host, port, retry - 1), delay, TimeUnit
                        .SECONDS);
            }
        });
    }
}
